package com.school.sports.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 志愿者申请表实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("volunteer_application")
public class VolunteerApplication {

    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户ID
     */
    @NotNull(message = "用户ID不能为空")
    private Long userId;

    /**
     * 项目ID
     */
    private Long projectId;

    /**
     * 场地ID
     */
    private Integer venueId;

    /**
     * 服务意向
     */
    @Size(max = 1000, message = "服务意向长度不能超过1000个字符")
    private String preference;

    /**
     * 状态：待审核、已通过、已驳回、已取消
     */
    private String status;

    /**
     * 驳回原因
     */
    @Size(max = 200, message = "驳回原因长度不能超过200个字符")
    private String rejectReason;

    /**
     * 创建时间
     */
    private LocalDateTime createdAt;

    /**
     * 用户对象（关联查询时使用）
     */
    @TableField(exist = false)
    private User user;

    /**
     * 项目对象（关联查询时使用）
     */
    @TableField(exist = false)
    private Project project;

    /**
     * 场地对象（关联查询时使用）
     */
    @TableField(exist = false)
    private Venue venue;

    /**
     * 用户姓名（关联查询时使用）
     */
    @TableField(exist = false)
    private String userName;

    /**
     * 项目名称（关联查询时使用）
     */
    @TableField(exist = false)
    private String projectName;

    /**
     * 场地名称（关联查询时使用）
     */
    @TableField(exist = false)
    private String venueName;

    /**
     * 申请状态枚举
     */
    public enum ApplicationStatus {
        PENDING("待审核"),
        APPROVED("已通过"),
        REJECTED("已驳回"),
        CANCELLED("已取消");

        private final String displayName;

        ApplicationStatus(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }

        /**
         * 根据显示名称获取枚举值
         */
        public static ApplicationStatus fromDisplayName(String displayName) {
            for (ApplicationStatus status : ApplicationStatus.values()) {
                if (status.getDisplayName().equals(displayName)) {
                    return status;
                }
            }
            return null;
        }
    }

    /**
     * 设置申请状态
     */
    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * 获取申请状态显示名称
     */
    public String getStatusDisplayName() {
        ApplicationStatus statusEnum = ApplicationStatus.fromDisplayName(this.status);
        return statusEnum != null ? statusEnum.getDisplayName() : this.status;
    }

    /**
     * 检查是否待审核
     */
    public boolean isPending() {
        return ApplicationStatus.PENDING.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已通过
     */
    public boolean isApproved() {
        return ApplicationStatus.APPROVED.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已驳回
     */
    public boolean isRejected() {
        return ApplicationStatus.REJECTED.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已取消
     */
    public boolean isCancelled() {
        return ApplicationStatus.CANCELLED.getDisplayName().equals(this.status);
    }

    /**
     * 通过申请
     */
    public void approveApplication() {
        this.status = ApplicationStatus.APPROVED.getDisplayName();
        this.rejectReason = null;
    }

    /**
     * 驳回申请
     */
    public void rejectApplication(String reason) {
        this.status = ApplicationStatus.REJECTED.getDisplayName();
        this.rejectReason = reason;
    }

    /**
     * 取消申请
     */
    public void cancelApplication() {
        this.status = ApplicationStatus.CANCELLED.getDisplayName();
        this.rejectReason = null;
    }

    /**
     * 检查是否可以修改状态
     */
    public boolean canModifyStatus() {
        return isPending();
    }

    /**
     * 检查申请是否有效
     */
    public boolean isValid() {
        return userId != null && (projectId != null || venueId != null);
    }

    /**
     * 获取申请显示信息
     */
    public String getApplicationDisplay() {
        StringBuilder display = new StringBuilder();
        display.append(userName != null ? userName : "未知用户");

        if (projectName != null) {
            display.append(" - 项目：").append(projectName);
        }

        if (venueName != null) {
            display.append(" - 场地：").append(venueName);
        }

        display.append(" (").append(getStatusDisplayName()).append(")");

        return display.toString();
    }

    /**
     * 获取状态标签样式（用于前端显示）
     */
    public String getStatusTagType() {
        if (isPending()) return "warning";
        if (isApproved()) return "success";
        if (isRejected()) return "danger";
        if (isCancelled()) return "info";
        return "info";
    }

    /**
     * 获取申请类型
     */
    public String getApplicationType() {
        if (projectId != null && venueId != null) {
            return "项目+场地";
        } else if (projectId != null) {
            return "项目服务";
        } else if (venueId != null) {
            return "场地服务";
        } else {
            return "通用服务";
        }
    }

    /**
     * 获取服务意向关键词
     */
    public List<String> getPreferenceKeywords() {
        if (preference == null || preference.trim().isEmpty()) {
            return Arrays.asList();
        }

        // 简单的关键词提取，实际可以更复杂
        String[] keywords = preference.split("[，,、；;\\s]+");
        return Arrays.asList(keywords)
                .stream()
                .filter(keyword -> keyword != null && keyword.trim().length() > 1)
                .distinct()
                .limit(5)
                .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 检查申请是否为紧急申请
     */
    public boolean isUrgent() {
        // 可以根据业务规则判断，比如申请时间距开始时间很近
        if (createdAt == null) return false;

        long hoursSinceCreation = java.time.Duration.between(
                createdAt, LocalDateTime.now()).toHours();

        return hoursSinceCreation <= 24;
    }

    /**
     * 获取申请处理时长
     */
    public String getProcessingDuration() {
        if (createdAt == null) return "未知";

        if (isPending()) {
            long hours = java.time.Duration.between(
                    createdAt, LocalDateTime.now()).toHours();
            return "待处理 " + hours + " 小时";
        } else {
            // 这里可以记录审核时间，简化处理
            return "已处理";
        }
    }

    /**
     * 从关联对象同步字段信息
     */
    public void syncFieldsFromObjects() {
        if (user != null) {
            this.userName = user.getRealName();
        }

        if (project != null) {
            this.projectName = project.getName();
        }

        if (venue != null) {
            this.venueName = venue.getName();
        }
    }

    /**
     * 获取所有可能的状态
     */
    public static List<String> getAllStatuses() {
        return Arrays.asList(
                ApplicationStatus.PENDING.getDisplayName(),
                ApplicationStatus.APPROVED.getDisplayName(),
                ApplicationStatus.REJECTED.getDisplayName(),
                ApplicationStatus.CANCELLED.getDisplayName()
        );
    }

    /**
     * 检查申请信息是否完整
     */
    public boolean isProfileComplete() {
        return userId != null
                && preference != null && !preference.trim().isEmpty()
                && (projectId != null || venueId != null);
    }

    /**
     * 获取申请摘要信息
     */
    public String getApplicationSummary() {
        StringBuilder summary = new StringBuilder();
        summary.append("申请人：").append(userName != null ? userName : "未知").append("\n");
        summary.append("申请类型：").append(getApplicationType()).append("\n");
        summary.append("服务意向：").append(preference != null ? preference : "无").append("\n");
        summary.append("申请状态：").append(getStatusDisplayName()).append("\n");
        summary.append("申请时间：").append(createdAt != null ? createdAt.toString() : "未知");

        if (isRejected() && rejectReason != null) {
            summary.append("\n驳回原因：").append(rejectReason);
        }

        return summary.toString();
    }

    /**
     * 检查是否可以转为志愿者任务
     */
    public boolean canConvertToTask() {
        return isApproved() && isProfileComplete();
    }

    /**
     * 获取推荐的任务内容
     */
    public String getRecommendedTaskContent() {
        if (preference == null || preference.trim().isEmpty()) {
            return "通用志愿服务";
        }

        // 基于服务意向推荐任务内容
        if (preference.contains("引导")) {
            return "参赛选手引导和咨询服务";
        } else if (preference.contains("场地")) {
            return "场地布置和设备管理";
        } else if (preference.contains("器材")) {
            return "器材分发和回收";
        } else if (preference.contains("记录")) {
            return "成绩记录和文档整理";
        } else {
            return "综合志愿服务";
        }
    }

    /**
     * 获取申请紧急程度
     */
    public String getUrgencyLevel() {
        if (!isPending()) return "已完成";

        long hoursSinceCreation = java.time.Duration.between(
                createdAt, LocalDateTime.now()).toHours();

        if (hoursSinceCreation <= 12) {
            return "紧急";
        } else if (hoursSinceCreation <= 48) {
            return "一般";
        } else {
            return "低优先级";
        }
    }

    /**
     * 获取申请处理建议
     */
    public String getProcessingSuggestion() {
        if (!isPending()) return "";

        if (isUrgent()) {
            return "建议尽快处理，紧急申请";
        }

        if (projectId != null && project != null) {
            return "需关注项目开始时间";
        }

        if (venueId != null && venue != null) {
            return "需考虑场地使用安排";
        }

        return "按正常流程处理";
    }
}